package com.wh.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.wh.system.dao.EmployeeRoleDao;
import com.wh.system.dao.MenuDao;
import com.wh.system.dao.RoleMenuDao;
import com.wh.system.dao.RolePermissionDao;
import com.wh.system.dto.MenuDto;
import com.wh.system.pojo.*;
import com.wh.system.service.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class MenuServiceimpl implements IMenuService {


    @Autowired
    private MenuDao menuDao;
    @Autowired
    private RoleMenuDao roleMenuDao;
    @Autowired
    private RolePermissionDao rolePermissionDao;

    @Override
    public void add(Menu menu) {
        menuDao.insert(menu);
    }

    @Override
    public void del(Long id) {
        menuDao.deleteById(id);
    }

    @Override
    public void upd(Menu menu) {
        menuDao.updateById(menu);
    }

    @Override
    public List<Menu> findAll() {

        return menuDao.selectList(null);
    }

    @Override
    public Menu findById(Long id) {
        return menuDao.selectById(id);
    }


    @Override
    public void patchDel(List<Long> ids) {
        menuDao.deleteBatchIds(ids);
    }

    /*@Override
    public Map<String, Object> menuTree(Long roleId) {
        Map<String, Object> result = new HashMap<>();
        ArrayList<Long> checkedMenuKeys = Lists.newArrayList(); // 用于保存已选中的菜单ID
        ArrayList<Long> checkedPermissionKeys = Lists.newArrayList(); // 用于保存已选中的权限ID
        if (roleId != null) {
            // 获取角色拥有的菜单权限
            ArrayList<Long> menuIds = Lists.newArrayList();
            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleMenu::getRoleId, roleId);
            List<RoleMenu> roleMenus = roleMenuDao.selectList(queryWrapper);
            if (!ObjectUtil.isEmpty(roleMenus)) {
                for (RoleMenu roleMenu : roleMenus) {
                    menuIds.add(roleMenu.getMenuId());
                }
                checkedMenuKeys.addAll(menuIds); // 将菜单ID添加到已选中的菜单键中
            }

            // 获取角色的其他权限
            ArrayList<Long> permissionIds = Lists.newArrayList();
            LambdaQueryWrapper<RolePermission> permissionQueryWrapper = new LambdaQueryWrapper<>();
            permissionQueryWrapper.eq(RolePermission::getRoleId, roleId);
            List<RolePermission> rolePermissions = rolePermissionDao.selectList(permissionQueryWrapper);
            if (!ObjectUtil.isEmpty(rolePermissions)) {
                for (RolePermission rolePermission : rolePermissions) {
                    permissionIds.add(rolePermission.getPermissionId());
                }
                checkedPermissionKeys.addAll(permissionIds); // 将权限ID添加到已选中的权限键中
            }
        }

        result.put("checkedMenuKeys", checkedMenuKeys);
        result.put("checkedPermissionKeys", checkedPermissionKeys);


//        查询所有菜单
        List<Menu> menus = menuDao.selectList(null);
//        避免 双重for循环 使用map集合
        Map<Long, Menu> map = new HashMap<>();

//        遍历添加
        for (Menu menu : menus) {
            map.put(menu.getId(), menu);
        }

//        3创建最终的菜单树集合
        ArrayList<Menu> menuTree = new ArrayList<>();
        for (Long id : map.keySet()) {
            Menu menu = map.get(id);
            if (menu.getParentId() != null) {
                //先获取到父菜单
                Long parentId = menu.getParentId();
                //从map中获取父菜单对象
                Menu parentObj = map.get(parentId);
                parentObj.getChildren().add(menu);
            }
        }
        for (Long menuId : map.keySet()) {
            Menu menu = map.get(menuId);
            if (menu.getParentId() == null) {
                menuTree.add(menu);
            }
        }
        result.put("allMenuTree", menuTree);
        //返回菜单树
        return result;
    }
*/
    @Override
    public Map<String, Object> menuTree(Long roleId) {
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> checkedKeys = new HashMap<>(); // 新的Map用于存储菜单和权限键

        List<Long> menuIds = new ArrayList<>(); // 用于存储角色拥有的菜单ID
        List<Long> permissionIds = new ArrayList<>(); // 用于存储角色拥有的权限ID



        // 获取角色拥有的菜单权限
        if (roleId != null) {
            // 查询角色拥有的菜单权限
            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleMenu::getRoleId, roleId);
            List<RoleMenu> roleMenus = roleMenuDao.selectList(queryWrapper);
            if (!ObjectUtil.isEmpty(roleMenus)) {
                for (RoleMenu roleMenu : roleMenus) {
                    menuIds.add(roleMenu.getMenuId());
                }
            }

            // 查询角色拥有的其他权限
            List<RolePermission> rolePermissions = rolePermissionDao.selectList(new LambdaQueryWrapper<RolePermission>().eq(RolePermission::getRoleId, roleId));
            for (RolePermission rolePermission : rolePermissions) {
                permissionIds.add(rolePermission.getPermissionId());
            }
        }

        checkedKeys.put("menuIds", menuIds); // 存储菜单ID列表
        checkedKeys.put("permissionIds", permissionIds); // 存储权限ID列表

        // 获取角色拥有的菜单权限
//        if (roleId != null) {
//            ArrayList<Long> menuIds = Lists.newArrayList();
//            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.eq(RoleMenu::getRoleId, roleId);
//            List<RoleMenu> roleMenus = roleMenuDao.selectList(queryWrapper);
//            if (!ObjectUtil.isEmpty(roleMenus)) {
//                for (RoleMenu roleMenu : roleMenus) {
//                    menuIds.add(roleMenu.getMenuId());
//                }
//                allCheckedKeys.addAll(menuIds); // 将菜单ID添加到已选中的键中
//            }
//
//            // 获取角色的其他权限
//            ArrayList<Long> permissionIds = Lists.newArrayList();
//            LambdaQueryWrapper<RolePermission> permissionQueryWrapper = new LambdaQueryWrapper<>();
//            permissionQueryWrapper.eq(RolePermission::getRoleId, roleId);
//            List<RolePermission> rolePermissions = rolePermissionDao.selectList(permissionQueryWrapper);
//            if (!ObjectUtil.isEmpty(rolePermissions)) {
//                for (RolePermission rolePermission : rolePermissions) {
//                    permissionIds.add(rolePermission.getPermissionId());
//                }
//                allCheckedKeys.addAll(permissionIds); // 将权限ID添加到已选中的键中
//            }
//        }
//        checkedKeys.put("allCheckedKeys", allCheckedKeys);

        // 查询所有菜单
        List<Menu> menus = menuDao.selectList(null);
        Map<Long, Menu> map = new HashMap<>();

        for (Menu menu : menus) {
            map.put(menu.getId(), menu);
        }

        ArrayList<Menu> menuTree = new ArrayList<>();
        for (Long id : map.keySet()) {
            Menu menu = map.get(id);
            if (menu.getParentId() != null) {
                Long parentId = menu.getParentId();
                Menu parentObj = map.get(parentId);
                parentObj.getChildren().add(menu);
            }
        }
        for (Long menuId : map.keySet()) {
            Menu menu = map.get(menuId);
            if (menu.getParentId() == null) {
                menuTree.add(menu);
            }
        }

        result.put("checkedKeys", checkedKeys); // 存储合并后的键Map
        result.put("allMenuTree", menuTree);

        return result;
    }


   /* public List<Menu> menuTree() {
        //1. 一次性查询出所有数据，放到内存中，可以使用map
        List<Menu> allMenus = menuDao.selectList(null);
        //2. 重组数据(Menu ID - Menu 信息)，方便查找
        Map<Long, Menu> menuMap = new HashMap<>();
        for (Menu menu : allMenus) {
            menuMap.put(menu.getId(), menu);
        }
        //3. 创建菜单树结果集（树结果中直接存储的都是主菜单，其他菜单和权限存储在子菜单中）
        List<Menu> menuTree = new ArrayList<>();
        //4. 遍历所有的菜单，开始添加树信息
        for (Menu menu : allMenus) {
            if (menu.getParentId() == null) { // 如果为null，就是主菜单。
                // 4.0 如果是主菜单，就添加到结果集中
                menuTree.add(menu);
            } else {   // 如果不为null，就添加到父菜单的所属儿子中
                // 4.1 获取当前菜单的父菜单ID
                Long parentId = menu.getParentId();
                // 4.2 从第2步整理好的信息中获取对应的父菜单信息
                Menu parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    // 将自己装到父菜单的children中
                    parentMenu.getChildren().add(menu);
                }
            }
        }
        return menuTree;

    }
*/

    public IPage<Menu> findByPage(MenuDto menuDto){
        QueryWrapper<Menu> qw = new QueryWrapper<>();
        //2.组件分页数据
        IPage<Menu> page = new Page<>(menuDto.getCurrentPage(), menuDto.getPageSize());
        List<Menu> byPage = menuDao.findByPage(page, qw);
        System.out.println(byPage);
        page.setRecords(byPage);
        page.setTotal(menuDao.selectCount(qw));
        //3.返回
        return page;
    }

    /**
     * 获取所有菜单路径
     *
     * @return 菜单路径<菜单ID, 菜单路径>
     */
    @Override
    public Map<Long, String> menuPath() {
        //1.查询所有菜单
        Map<String, Object> map = menuTree(null);
        ArrayList<Menu> menuTree = (ArrayList<Menu>) map.get("allMenuTree");
        //2.定义存储菜单路径的集合
        Map<Long, String> menuPath = new HashMap<>();
        //3.遍历添加
        for (Menu menu : menuTree) {
            //3.1 添加顶级部门
            menuPath.put(menu.getId(), "/" + menu.getId());
            //3.2 添加当前顶级部门的子部门
            setFullPath(menuPath, menu.getChildren());
        }
        //4.返回
        return menuPath;
    }
    private void setFullPath(Map<Long, String> menuPath, List<Menu> childrenMenuTree) {
        //如果没有子部门，则停止
        if (ObjectUtil.isEmpty(childrenMenuTree)) {
            return;
        }
        //如果有子部门，则便利子部门
        for (Menu menu : childrenMenuTree) {
            String parentPath = menuPath.get(menu.getParentId());
            menuPath.put(menu.getId(), parentPath + "/" + menu.getId());
            setFullPath(menuPath, menu.getChildren());
        }
    }

    @Override
    public List<Menu> selectMenuList(Long userId) {
        return null;
    }

    @Override
    public List<Menu> selectMenuList(Menu menu, Long userId) {
        return null;
    }

    @Override
    public List<Long> selectMenuListByRoleId(Long roleId) {
        return null;
    }

    @Override
    public List<TreeSelect> buildMenuTreeSelect(List<Menu> menus) {
        return null;
    }

}
